package com.run2code.idea.plugin.codegenerate.biz.generate.service;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.run2code.idea.plugin.codegenerate.biz.generate.content.CodeGenContext;
import com.run2code.idea.plugin.codegenerate.biz.generate.template.TemplateFactory;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;

/**
 * 抽象的代码生成器
 * 关注公众号【奔跑的码畜】，一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/10/30
 */
public abstract class AbstractCodeGenerator implements ICodeGenerator {

    @Override
    public void generation(Project project, CodeGenContext codeGenContext) {
        doGenerate(project, codeGenContext);
    }

    /**
     * 真正的生成方法,交给子类实现
     *
     * @param project 工程
     * @param codeGenContext 代码生成上下文
     */
    protected abstract void doGenerate(Project project, CodeGenContext codeGenContext);

    public void writeFile(Project project, String packageName, String name, String ftl, Object dataModel, Boolean useLocalTemplate) {
        VirtualFile virtualFile;
        try {
            virtualFile = createPackageDir(packageName).createChildData(project, name);
            StringWriter stringWriter = new StringWriter();
            Template template = TemplateFactory.getInstance(ftl, useLocalTemplate);
            template.process(dataModel, stringWriter);
            virtualFile.setBinaryContent(stringWriter.toString().getBytes(StandardCharsets.UTF_8));
        } catch (IOException | TemplateException e) {
            throw new RuntimeException(e);
        }
    }


    private static VirtualFile createPackageDir(String packageName) {
        String path = FileUtil.toSystemIndependentName(StringUtil.replace(packageName, ".", "/"));
        new File(path).mkdirs();
        return LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
    }

}
